import { Icon, NavBar, Toast } from "antd-mobile";
import React from 'react';
import { connect } from "react-redux";
import { List } from "react-virtualized";
import { changeCityAction } from "../../store/actions/actionCreator";
// import TestReactVirtualized from "../../demo/TestReactVirtualized";
import styles from './index.module.scss';


/* 
    1. 按照布局需求，自己处理后端返回的数据
    2. 虚拟化列表的应用
    3. 点击城市名称改变 redux 仓库的数据
      - 只有 北京，上海，广州，深圳 才有房源数据，
      - 其他没有房源数据的提示，功能升级中...
*/

class CitySelect extends React.Component {
  state = {
    // 城市列表数据
    cityListData: [],
    // 字母列表
    letterList: [],
    // 选中状态的索引
    activeIndex: 0,
  };
  componentDidMount() {
    // 根据请求处理成城市列表所需的渲染格式
    this.createCityListData();
    // this.getHotCity();
    // this.getAllCity();
    // console.log(this.ListRef);
  }
  // 创造所需的列表数据格式
  createCityListData = async () => {
    // 自己设计的城市列表数据
    let cityListData = [];
    // 第一部分：当前城市添加到城市选择数组中
    cityListData.push({
      title: '当前城市',
      children: [{ cityName: '广州', value: '11' }]
    });
    // 第二部分：热门城市添加到城市选择数组中
    const hotCity = await this.getHotCity();
    console.log('hotCity', hotCity);
    cityListData.push({
      title: '热门城市',
      children: hotCity.map(item => ({ cityName: item.label, value: item.value }))
    });
    // 第三部分：所有城市<按字母>添加到城市选择数组中
    const allCity = await this.getAllCity();
    // 按照城市缩写进行数组排序
    allCity.sort((a, b) => a.short > b.short ? 1 : -1);

    // 遍历所有城市
    allCity.forEach(item => {
      // 提取首字母
      const firstLetter = item.short.charAt(0).toUpperCase();
      // 城市列表中是否有当前的首字母
      //    - 如果没有：就新增当前首字母作为标题 title
      //    - 如果有： 把当前城市作为孩子最近到 children 数组中
      const index = cityListData.findIndex(item2 => firstLetter === item2.title);
      // 如果没有标题
      if (index === -1) {
        // 新创建一个首字母开头的标题
        cityListData.push({
          title: firstLetter,
          children: [{ cityName: item.label, value: item.value }]
        });
      } else {
        // 作为孩子添加到当前字母的 children 数组中
        cityListData[index].children.push({ cityName: item.label, value: item.value });
      }
    });

    // console.log('allCity', allCity);

    // 最终的数据查看
    // console.log('前端设计的列表cityListData', cityListData);
    const letterList = cityListData.map(item => item.title);
    // .splice(开始删除的索引, 删除的个数, 添加的数据1, 添加的数据2)  
    // 从索引值 0 开始删除 2 个数组，再添加 '#', '热'
    letterList.splice(0, 2, '#', '热');
    // console.log('letterList', letterList);
    // 设置为组件的状态
    this.setState({ cityListData, letterList });

    // 根据准确的测量每一行数据的高度，而不是默认的估算的高度
    this.ListRef.current.measureAllRows();
  };
  // 获取热门城市的请求
  getHotCity() {
    return this.$axios.get('/area/hot');
  }
  // 获取所有城市的请求
  getAllCity() {
    return this.$axios.get('/area/city?level=1');
  }
  // 改变仓库中的城市数据
  changeCity = (cityName) => {
    // console.log(cityName);
    // console.log(this.state.cityListData);
    // 获取到数据中的热门城市，因为只有热门城市有房源数据
    const hotCityList = this.state.cityListData[1].children;
    // 判断当前点击的城市是否为热门城市
    const index = hotCityList.findIndex(item => item.cityName === cityName);
    // 如果是热门城市
    if (index !== -1) {
      // console.log('热门城市，改变仓库数据');
      this.props.changeStoreCity(hotCityList[index].cityName);
      // console.log(this.props);
      this.props.history.replace('/home');
    } else {
      // 如果不是热门热门城市
      // console.log('非热门城市，弹窗提示');
      Toast.info('城市房源真正完善中...', 1);
    }
  };
  // 虚拟化列表 - 用于渲染虚拟列表的函数
  rowRenderer = ({ key, index, isScrolling, isVisible, style, }) => {
    // console.log(key, style, list[index]);
    const item = this.state.cityListData[index];
    // console.log('虚拟化列表一行的数据', item);
    return (
      <div key={key} style={style}>
        {/* 大行的标题 */}
        <div className={styles.row_title}> {item.title} </div>
        {/* 大行的城市 */}
        {item.children.map(item2 =>
          <div
            key={item2.value}
            className={styles.row_children}
            onClick={() => { this.changeCity(item2.cityName); }}
          >
            {item2.cityName}
          </div>
        )}
      </div>
    );
  };
  // 虚拟化列表 - 计算大行的高度
  rowHeight = ({ index }) => {
    return 40 + this.state.cityListData[index].children.length * 40;
  };
  // 当行被渲染时
  onRowsRendered = ({ startIndex }) => {
    // 如果不相等的时候，才更新右侧字母列表
    if (startIndex !== this.state.activeIndex) {
      console.log('startIndex', startIndex);
      // 每次 setState 会触发 render，添加判断进行优化，减少不必要的渲染
      this.setState({ activeIndex: startIndex });
    }
  };
  // 创建 List 组件的 ref 关联
  ListRef = React.createRef();
  render() {
    return (
      <>
        {/* 1.0 页面标题 */}
        <NavBar
          icon={<Icon type="left" />}
          onLeftClick={() => this.props.history.go(-1)}
        >城市选择</NavBar>
        {/* 2.0 右侧字母列表 */}
        <div className={styles.letter_list}>
          {this.state.letterList.map((item, index) =>
            <span
              key={item}
              className={index === this.state.activeIndex ? styles.active : ''}
              onClick={() => {
                // 更新字母的选中状态
                this.setState({ activeIndex: index });
                // 通过方法的方式改变列表滚动的索引，功能同组件的 scrollToIndex 属性
                this.ListRef.current.scrollToRow(index);
              }}
            >{item}</span>
          )}
        </div>
        {/* 3.0 左侧城市列表 - 虚拟化列表 */}
        <List
          width={window.screen.width}
          height={window.screen.height - 45}
          rowCount={this.state.cityListData.length}   // 大行的长度
          rowHeight={this.rowHeight}                  // 计算大行高度
          rowRenderer={this.rowRenderer}              // 大行渲染
          // scrollToIndex={this.state.activeIndex}      // 滚动到哪个索引
          scrollToAlignment="start"                   // 顶部对齐
          onRowsRendered={this.onRowsRendered}        // 当行被渲染时
          ref={this.ListRef}                          // 通过 ref 定位到 List 组件
        />
      </>
    );
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    changeStoreCity: (cityName) => {
      dispatch(changeCityAction(cityName));
    }
  };
};


export default connect(null, mapDispatchToProps)(CitySelect);